package com.fattyCorps.service;

import com.fattyCorps.cache.PlayerCache;
import com.fattyCorps.config.gameConfig.GlobalConfig;
import com.fattyCorps.config.gameConfig.HeroConfig;
import com.fattyCorps.exception.gameException.CoinNotEnoughErrorException;
import com.fattyCorps.exception.gameException.gacha.FreeGachaTimeErrorException;
import com.fattyCorps.exception.gameException.gacha.GachaFormatErrorException;
import com.fattyCorps.obj.cache.PlayerInfo;
import com.fattyCorps.obj.db.Player;
import com.fattyCorps.obj.mould.HeroMould;
import com.fattyCorps.obj.msg.SRet;
import com.fattyCorps.obj.msg.server.gacha.SFreeRollInfoMsg;
import com.fattyCorps.obj.msg.server.gacha.SGetCachaInfoMsg;
import com.fattyCorps.obj.msg.server.gacha.SOneCoinRollMsg;
import com.fattyCorps.obj.msg.server.gacha.STenCoinRollsMsg;
import com.fattyCorps.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class GachaService {

    @Autowired
    PlayerCache playerCache;

    @Autowired
    GlobalConfig globalConfig;

    @Autowired
    HeroConfig heroConfig;

    @Autowired
    HeroService heroService;

    @Autowired
    PlayerService playerService;

    //打开抽卡页面获取信息
    public SRet<Object> getGachaInfo(Integer playerId) {
        PlayerInfo playerInfo = playerCache.getPlayerInfo(playerId);
        String lastFreeRollTime = playerInfo.getBaseProp().getLastFreeRollTime();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtils.YYYY_MM_DD_HH_MM_SS);

        Calendar calendar = Calendar.getInstance();
        int curYear = calendar.get(Calendar.YEAR);
        int curMonth = calendar.get(Calendar.MONTH) + 1;
        int curDay = calendar.get(Calendar.DATE);

        //todo 增加一种抽卡方式 1.每日固定时间刷新免费抽卡一次
        //获取用户上次免费抽卡时间计算日期是否为当前服务器日期

        //2.固定间隔时间刷新
        //获取用户上次免费抽卡时间计算与当前时间间隔是否超过刷新时间
        Integer lastFreeTime = getLsatFreeTime(playerId);

        if (lastFreeTime < 0) {
            lastFreeTime = 0;
        }

        // todo:查询抽卡道具数量，先写0

        SGetCachaInfoMsg sGetCachaInfoMsg = new SGetCachaInfoMsg();
        sGetCachaInfoMsg.setLastFreeTime(lastFreeTime);
        sGetCachaInfoMsg.setItemNum(0);
        return SRet.success(sGetCachaInfoMsg);
    }

    //免费单抽
    public SRet freeRoll(Integer playerId) {
        Integer lastFreeTime = getLsatFreeTime(playerId);

        if (lastFreeTime > 0) {
            throw new FreeGachaTimeErrorException();
        }

        PlayerInfo playerInfo = playerCache.getPlayerInfo(playerId);
        Player baseProp = playerInfo.getBaseProp();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtils.YYYY_MM_DD_HH_MM_SS);
        String curTimeStr = simpleDateFormat.format(new Date());
        baseProp.setLastFreeRollTime(curTimeStr);

        Integer heroTypeId = randHeroTypeId();

        heroService.createHero(playerId, heroTypeId);

        SFreeRollInfoMsg sFreeRollInfoMsg = new SFreeRollInfoMsg();
        sFreeRollInfoMsg.setHeroTypeId(heroTypeId);

        return SRet.success(sFreeRollInfoMsg);
    }

    //免费单抽刷新倒计时
    private Integer getLsatFreeTime(Integer playerId) {
        PlayerInfo playerInfo = playerCache.getPlayerInfo(playerId);
        String lastFreeRollTime = playerInfo.getBaseProp().getLastFreeRollTime();
        Integer freeDisRollTime = globalConfig.getIntValue(GlobalConfig.FREE_COLL_TIME);

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtils.YYYY_MM_DD_HH_MM_SS);

        long lastFreeRollUnixTime = 0;
        try {
            lastFreeRollUnixTime = simpleDateFormat.parse(lastFreeRollTime).getTime() / 1000;
        } catch (Exception e) {
            log.error("getGachaInfo error: playerId=" + playerId + " lastFreeRollTime=" + lastFreeRollTime);
            throw new GachaFormatErrorException();
        }

        Date date = new Date();
        long curTime = date.getTime() / 1000;

        long lastFreeTime = lastFreeRollUnixTime + freeDisRollTime - curTime;
        return (int) lastFreeTime;
    }

    //单抽
    public SRet oneCoinRoll(Integer playerId) {
        //判断数量并扣除
        Integer oneRollCoin = globalConfig.getIntValue(GlobalConfig.ONE_ROLL_COIN);
        boolean b = playerService.addCoin(playerId, -oneRollCoin);
        if (!b) {
            throw new CoinNotEnoughErrorException();
        }
        //根据权重随机获取英雄
        Integer heroTypeId = randHeroTypeId();
        //创建英雄
        heroService.createHero(playerId, heroTypeId);

        SOneCoinRollMsg sOneCoinRollMsg = new SOneCoinRollMsg();
        sOneCoinRollMsg.setHeroTypeId(heroTypeId);
        sOneCoinRollMsg.setNewCoin(playerService.getCoin(playerId));

        return SRet.success(sOneCoinRollMsg);
    }

    //十连抽
    public SRet tenCoinRolls(Integer playerId) {
        //判断数量并扣除
        Integer tenRollsCoin = globalConfig.getIntValue(GlobalConfig.TEN_ROLLS_COIN);
        boolean b = playerService.addCoin(playerId, -tenRollsCoin);
        if (!b) {
            throw new CoinNotEnoughErrorException();
        }
        //根据权重随机获取英雄
        List<Integer> heroTypeIdList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Integer heroTypeId = randHeroTypeId();
            //创建英雄
            heroService.createHero(playerId, heroTypeId);
            heroTypeIdList.add(heroTypeId);
        }

        STenCoinRollsMsg sTenCoinRollsMsg = new STenCoinRollsMsg();
        sTenCoinRollsMsg.setHeroTypeIdList(heroTypeIdList);
        sTenCoinRollsMsg.setNewCoin(playerService.getCoin(playerId));

        return SRet.success(sTenCoinRollsMsg);
    }

    private Integer randHeroTypeId() {
        //遍历英雄模板，计算总权重
        List<HeroMould> heroMouldList = heroConfig.getHeroMouldList();
        Integer allWeight = heroConfig.getAllWeight();
        Random random = new Random();
        // 生成0-allWeight-1随机权重值
        Integer rand = random.nextInt(allWeight);

        Integer heroTypeId = 0;
        Integer heroWeightB = 0;

        //再次遍历,找到rand所在的英雄权重区间
        for (int i = 0; i < heroMouldList.size(); i++) {
            HeroMould heroMould = heroMouldList.get(i);
            Integer weight = heroMould.getRollWeight();
            if (heroWeightB <= rand && heroWeightB + weight > rand) {
                // 抽中的是这个
                heroTypeId = heroMould.getId();
                break;
            }
            heroWeightB += weight;
        }

        return heroTypeId;
    }
}
